package com.topvision.myviewtest.viewdrag.no;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.FrameLayout;

/**
 * @author lucy
 * @date 2018-02-11 13:32
 * @description //TODO
 */

public class DragView extends FrameLayout {
    private static final String TAG = "DragView";
    private int mTouchSlop;
    private View mDragView;
    private State mCurrentState;
    private float mLastX;
    private float mLastY;

    private float mDragViewOrigX;
    private float mDragViewOrigY;

    public DragView(Context context) {
        this(context, null);
    }

    public DragView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mTouchSlop = ViewConfiguration.getWindowTouchSlop();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                if (isFocusOnView(event)) {
                    mCurrentState = State.DRAGGING;
                    mLastX = event.getX();
                    mLastY = event.getY();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                int deltaX = (int) (event.getX() - mLastX);
                int deltaY = (int) (event.getY() - mLastY);

                if (mCurrentState == State.DRAGGING && mDragView != null
                        && (Math.abs(deltaX) > mTouchSlop || Math.abs(deltaY) > mTouchSlop)) {
                    ViewCompat.offsetLeftAndRight(mDragView, deltaX);
                    ViewCompat.offsetTopAndBottom(mDragView, deltaY);

                    mLastX = event.getX();
                    mLastY = event.getY();
                }
                break;
            case MotionEvent.ACTION_UP:
                if (mCurrentState == State.DRAGGING) {
//                    mCurrentState = State.IDEL;
//                    mDragView = null;
                    // 添加回弹效果
                    if (mDragView != null) {
                        ValueAnimator valueXAnimator = ValueAnimator.ofFloat(mDragView.getX(), mDragViewOrigX);
                        valueXAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                            @Override
                            public void onAnimationUpdate(ValueAnimator animation) {
                                mDragView.setX((Float) animation.getAnimatedValue());
                            }
                        });

                        ValueAnimator valueYAnimator = ValueAnimator.ofFloat(mDragView.getY(), mDragViewOrigY);
                        valueYAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                            @Override
                            public void onAnimationUpdate(ValueAnimator animation) {
                                mDragView.setY((Float) animation.getAnimatedValue());
                            }
                        });

                        AnimatorSet animatorSet = new AnimatorSet();
                        animatorSet.play(valueXAnimator).with(valueYAnimator);
                        animatorSet.addListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationEnd(Animator animation) {
                                super.onAnimationEnd(animation);
                                mDragView = null;
                                mCurrentState = State.IDEL;
                            }
                        });
                        animatorSet.start();
                    }
                }
                break;
            default:
                break;
        }
        return true;
    }

    private boolean isFocusOnView(MotionEvent event) {
        boolean result = false;
        Rect rect = new Rect();
        // 为了保证上层先动，逆序
        for (int i = getChildCount() - 1; i >= 0; i--) {
            View view = getChildAt(i);
            rect.set(
                    (int) view.getX(),
                    (int) view.getY(),
                    (int) (view.getX() + view.getWidth()),
                    (int) (view.getY() + view.getHeight()));

            if (rect.contains((int)event.getX(), (int)event.getY())) {
                // 在View视窗内部
                mDragView = view;
                result = true;

                // 保存移动前位置
                mDragViewOrigX = view.getX();
                mDragViewOrigY = view.getY();
                break;
            }
        }
        return result && mCurrentState != State.DRAGGING;
    }

    enum State {
        IDEL, DRAGGING
    }
}
